package com.ef.web.action;

import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;
import org.dom4j.Document;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.hibernate.Criteria;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;

import com.ef.constant.ConfirmMessage;
import com.ef.constant.EUserTodoObject;
import com.ef.constant.EUserTodoStatus;
import com.ef.constant.EUserTodoType;
import com.ef.domain.Department;
import com.ef.domain.Role;
import com.ef.domain.Team;
import com.ef.domain.User;
import com.ef.domain.UserTodoEvent;
import com.ef.service.DepartmentService;
import com.ef.service.LeadsService;
import com.ef.service.RoleService;
import com.ef.service.TeamService;
import com.ef.service.TodoEventService;
import com.ef.service.UserService;
import com.ef.util.CalendarUtil;
import com.ef.util.CustomExample;

public class TodoEventAction extends BaseAction<UserTodoEvent> {

	private static final long serialVersionUID = 1L;
	protected final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
			.getLog(TodoEventAction.class);

	private TodoEventService todoEventService;

	private DepartmentService departmentService;

	private RoleService roleService;

	private TeamService teamService;

	private UserService userService;

	private LeadsService leadsService;

	private Map<String, String> departmentList;

	private Map<String, String> roleList;

	private Map<String, String> teamList;

	private Date startDate;

	private Date endDate;

	private String todoEventStartTime;

	public String getTodoEventStartTime() {
		return todoEventStartTime;
	}

	public void setTodoEventStartTime(String todoEventStartTime) {
		this.todoEventStartTime = todoEventStartTime;
	}

	public String getTodoEventEndTime() {
		return todoEventEndTime;
	}

	public void setTodoEventEndTime(String todoEventEndTime) {
		this.todoEventEndTime = todoEventEndTime;
	}

	private String todoEventEndTime;

	protected void prepareModelInner(UserTodoEvent model) {
		model.setStatus(EUserTodoStatus.Valid);
	}

	private void fetchListData() {
		Map<String, String> departmentMap = new LinkedHashMap<String, String>();
		List<Department> depts = departmentService.findAll();
		for (Department d : depts) {
			departmentMap.put(d.getId().toString(), d.getSchool().getName()
					+ "'s " + d.getName());
		}
		departmentList = departmentMap;

		Map<String, String> roleMap = new LinkedHashMap<String, String>();
		List<Role> roles = roleService.findAll();
		for (Role r : roles) {
			roleMap.put(r.getId().toString(), r.getName());
		}
		roleList = roleMap;

		Map<String, String> teamMap = new LinkedHashMap<String, String>();
		List<Team> teams = teamService.findAll();
		for (Team t : teams) {
			teamMap.put(t.getId().toString(), t.getName());
		}
		teamList = teamMap;
	}

	/*
	 * <response result="true"> <cur_alert count="" expire=""/> <connect count=""/>
	 * <disconnect count=""/> <net_problem count=""/> </response>
	 */
	@SuppressWarnings("serial")
	public void monitor() {
		Element response = DocumentFactory.getInstance().createElement(
				"response");
		if (getSessionUser() == null) {
			response.addAttribute("result", "false");
			Document document = DocumentFactory.getInstance().createDocument();
			document.add(response);
		} else {
			int s = todoEventService.countTodo(new CustomExample<UserTodoEvent>(this.getModel()) {
						public void appendCondition(Criteria criteria) {
							this.excludeProperty("status");
							User user = getSessionUser();
							Disjunction or = Restrictions.disjunction();
							criteria.add(Restrictions.ge("reminderEndTime",	new Date()));
							criteria.add(Restrictions.le("reminderEndTime",	CalendarUtil.getEndOfToday()));
							criteria.add(Restrictions.le("reminderStartTime", new Date()));
							if (user != null) {
								Property myProperty = Property.forName("createUser.id");
								or.add(myProperty.eq(user.getId())); // 本人
								if (user.getDepartment() != null) {
									Property myProperty1 = Property.forName("toDepartment.id");
									or.add(myProperty1.eq(getSessionUser().getDepartment().getId()));
								}
								if (user.getTeam() != null) {
									Property myProperty1 = Property.forName("toTeam.id");
									or.add(myProperty1.eq(getSessionUser().getTeam().getId()));
								}
								if (user.getRole() != null) {
									Property myProperty2 = Property.forName("toRole.id");
									or.add(myProperty2.eq(getSessionUser().getRole().getId()));
								}
								Property myProperty3 = Property.forName("toUser.id");
								or.add(myProperty3.eq(user.getId()));
							}
							criteria.add(Restrictions.eq("status",	EUserTodoStatus.Valid));
							criteria.add(or);

						}
					});
			
			int s2 = todoEventService.countTodo(new CustomExample<UserTodoEvent>(this.getModel()) {
				public void appendCondition(Criteria criteria) {
					this.excludeProperty("status");
					User user = getSessionUser();
					Disjunction or = Restrictions.disjunction();
					criteria.add(Restrictions.le("reminderEndTime",	new Date()));

					if (user != null) {
						Property myProperty = Property.forName("createUser.id");
						or.add(myProperty.eq(user.getId())); // 本人
						if (user.getDepartment() != null) {
							Property myProperty1 = Property.forName("toDepartment.id");
							or.add(myProperty1.eq(getSessionUser().getDepartment().getId()));
						}
						if (user.getTeam() != null) {
							Property myProperty1 = Property.forName("toTeam.id");
							or.add(myProperty1.eq(getSessionUser().getTeam().getId()));
						}
						if (user.getRole() != null) {
							Property myProperty2 = Property.forName("toRole.id");
							or.add(myProperty2.eq(getSessionUser().getRole().getId()));
						}
						Property myProperty3 = Property.forName("toUser.id");
						or.add(myProperty3.eq(user.getId()));
					}
					criteria.add(Restrictions.eq("status",	EUserTodoStatus.Expired));
					criteria.add(or);

				}
			});
			response.addAttribute("result", "true");
			Element temp = response.addElement("content");
			temp.addAttribute("count", String.valueOf(s));
			temp.addAttribute("expire", String.valueOf(s2));
		}
		try {
			HttpServletResponse httpResponse = ServletActionContext.getResponse();
			httpResponse.setContentType("text/xml");
			httpResponse.setCharacterEncoding("UTF-8");
			PrintWriter out = httpResponse.getWriter();
			out.write(response.asXML());
		} catch (Exception ignore) {
			ignore.printStackTrace();
		}
	}

	@SuppressWarnings("serial")
	public String list() {
		if (endDate != null) {
			endDate.setTime(endDate.getTime() + 1000 * 24 * 60 * 60 - 1);
		}
		this.listResult = todoEventService.findByExample(
				new CustomExample<UserTodoEvent>(this.getModel()) {
					public void appendCondition(Criteria criteria) {
						if (startDate != null) {
							criteria.add(Restrictions.ge("reminderStartTime",
									startDate));
						}
						if (endDate != null) {
							criteria.add(Restrictions.le("reminderEndTime",
									endDate));
						}
						Disjunction or = Restrictions.disjunction();
						User user = getSessionUser();
						if (user != null) {
							Property myProperty = Property
									.forName("createUser.id");
							or.add(myProperty.eq(getSessionUser().getId())); // 本人
							if (getSessionUser().getDepartment() != null) {
								Property myProperty1 = Property
										.forName("toDepartment.id");
								or.add(myProperty1.eq(getSessionUser()
										.getDepartment().getId()));
							}

							if (getSessionUser().getTeam() != null) {
								Property myProperty1 = Property
										.forName("toTeam.id");
								or.add(myProperty1.eq(getSessionUser()
										.getTeam().getId()));
							}

							if (getSessionUser().getRole() != null) {
								Property myProperty2 = Property
										.forName("toRole.id");
								or.add(myProperty2.eq(getSessionUser()
										.getRole().getId()));
							}

							Property myProperty3 = Property
									.forName("toUser.id");
							or.add(myProperty3.eq(getSessionUser().getId()));
						}
						criteria.add(or);
						if (entity != null
								&& entity.getStatus() != null
								&& entity.getStatus().equals(
										EUserTodoStatus.Valid)) {
							criteria.addOrder(Order.asc("reminderEndTime"));
						} else {
							criteria.addOrder(Order.desc("reminderEndTime"));
						}
					}
				}, this.getStartIndex(), this.getPageSize());
		return LIST;
	}

	@SuppressWarnings("serial")
	public String mytask() {
		this.listResult = todoEventService.findByExample(
				new CustomExample<UserTodoEvent>(this.getModel()) {
					public void appendCondition(Criteria criteria) {
						this.excludeProperty("status");
						User user = getSessionUser();
						Disjunction or = Restrictions.disjunction();
						criteria.add(Restrictions.ge("reminderEndTime",
								new Date()));
						criteria.add(Restrictions.le("reminderEndTime",
								CalendarUtil.getEndOfToday()));
						criteria.add(Restrictions.le("reminderStartTime",
								 new Date()));
						if (user != null) {
							Property myProperty = Property
									.forName("createUser.id");
							or.add(myProperty.eq(user.getId())); // 本人
							if (user.getDepartment() != null) {
								Property myProperty1 = Property
										.forName("toDepartment.id");
								or.add(myProperty1.eq(getSessionUser()
										.getDepartment().getId()));
							}
							if (user.getTeam() != null) {
								Property myProperty1 = Property
										.forName("toTeam.id");
								or.add(myProperty1.eq(getSessionUser()
										.getTeam().getId()));
							}
							if (user.getRole() != null) {
								Property myProperty2 = Property
										.forName("toRole.id");
								or.add(myProperty2.eq(getSessionUser()
										.getRole().getId()));
							}
							Property myProperty3 = Property
									.forName("toUser.id");
							or.add(myProperty3.eq(user.getId()));
						}
						criteria.add(Restrictions.eq("status",
								EUserTodoStatus.Valid));
						criteria.add(or);
						criteria.addOrder(Order.asc("reminderEndTime"));
					}
				}, this.getStartIndex(),100);
		return LIST;
	}

	public void prepareEdit() {
		// this.getModel().setStatus(EUserTodoStatus.Valid);
		// this.getModel().setToObject(EUserTodoObject.MySelf);
		// this.getModel().setReminderStartTime(new Date());
		// todoEventStartTime="9:00 AM";
		// todoEventEndTime="5:00 PM";
		// this.getModel().setReminderEndTime(new Date());
		// this.getModel().setTodoType(EUserTodoType.Call);
	}

	public String edit() {
		fetchListData();
		if (this.entity.getId() == null) {
			this.getModel().setStatus(EUserTodoStatus.Valid);
			this.getModel().setToObject(EUserTodoObject.MySelf);
			this.getModel().setReminderStartTime(new Date());
			todoEventStartTime = "9:00 AM";
			todoEventEndTime = "5:00 PM";
			this.getModel().setReminderEndTime(new Date());
			this.getModel().setTodoType(EUserTodoType.Call);
		} else {
			if (entity.getReminderStartTime() != null
					&& entity.getReminderEndTime() != null) {
				todoEventStartTime = timeDf.format(entity
						.getReminderStartTime());
				todoEventEndTime = timeDf.format(entity.getReminderEndTime());
			} else {
				todoEventStartTime = "9:00 AM";
				todoEventEndTime = "5:00 PM";
			}
		}
		return EDIT;
	}

	public String view() {
		return VIEW;
	}

	private static SimpleDateFormat timeDf = new SimpleDateFormat("K:mm a",
			new Locale("en"));

	public String save() {
		Date time = null;
		if (entity.getReminderStartTime() != null
				&& entity.getReminderEndTime() != null) {
			if (todoEventStartTime != null
					&& todoEventStartTime.trim().length() > 0) {
				try {
					time = timeDf.parse(todoEventStartTime);
				} catch (ParseException e) {
					System.out.println("TodoEventAction parse time error");
				}
				entity.setReminderStartTime(CalendarUtil.getDateTime(entity
						.getReminderStartTime(), time));
			} else {
				entity.setReminderStartTime(CalendarUtil.getBeginOfDay(entity
						.getReminderStartTime()));
			}
			if (todoEventEndTime != null
					&& todoEventEndTime.trim().length() > 0) {
				try {
					time = timeDf.parse(todoEventEndTime);
				} catch (ParseException e) {
					System.out.println("TodoEventAction parse time error");
				}
				entity.setReminderEndTime(CalendarUtil.getDateTime(entity
						.getReminderEndTime(), time));
			} else {
				entity.setReminderEndTime(CalendarUtil.getEndOfDay(entity
						.getReminderEndTime()));
			}
		}
		User user = this.getSessionUser();
		UserTodoEvent userTodoEvent = this.getModel();
		EUserTodoObject todoObject = entity.getToObject();
		entity.setToDepartment(null);
		entity.setToRole(null);
		entity.setToTeam(null);
		entity.setToUser(null);
		if (todoObject != null) {
			if (todoObject.equals(EUserTodoObject.MySelf)) {
				entity.setToUser(user);
			} else if (todoObject.equals(EUserTodoObject.Department)) {
				if (entity.getToDepartmentId() != null) {
					entity.setToDepartment(departmentService.findById(entity
							.getToDepartmentId()));
				}
			} else if (todoObject.equals(EUserTodoObject.Team)) {
				if (entity.getToTeamId() != null) {
					entity
							.setToTeam(teamService.findById(entity
									.getToTeamId()));
				}
			} else if (todoObject.equals(EUserTodoObject.Role)) {
				if (entity.getToRoleId() != null) {
					entity
							.setToRole(roleService.findById(entity
									.getToRoleId()));
				}
			} else if (todoObject.equals(EUserTodoObject.User)) {
				if (entity.getToUserId() != null) {
					entity
							.setToUser(userService.findById(entity
									.getToUserId()));
				}
			}
		}
		if (entity.getTodoType() != null) {
			if (entity.getSelLeadsId() != null) {
				entity.setSelLeads(leadsService
						.findById(entity.getSelLeadsId()));
			}
		} else {
			entity.setSelLeads(null);
		}
		if (entity.getCreateTime() == null) {
			entity.setCreateTime(new Date());
			entity.setCreateUser(user);
		}
		;
		entity.setStatus(EUserTodoStatus.Valid);
		entity.setGoAction(entity.prepareAction());
		userTodoEvent.setUpdateTime(new Date());
		userTodoEvent.setUpdateUser(getSessionUser());
		todoEventService.saveOrUpdate(userTodoEvent);
		this.setResult(ConfirmMessage.UserTodoEvent);
		fetchListData();
		return EDIT;
	}

	public String delete() {
		UserTodoEvent userTodoEvent = this.getModel();
		userTodoEvent.setStatus(EUserTodoStatus.Cancel);
		userTodoEvent.setFinishTime(new Date());
		userTodoEvent.setFinishUser(getSessionUser());
		todoEventService.saveOrUpdate(userTodoEvent);

		return "delete1";
	}

	public String finish() {
		String ids = getRequest().getParameter("ids");
		String[] id = ids.split(",");
		for (String i : id) {
			UserTodoEvent userTodoEvent = todoEventService.findById(Long
					.valueOf(i.trim()));
			userTodoEvent.setStatus(EUserTodoStatus.Finished);
			userTodoEvent.setFinishTime(new Date());
			userTodoEvent.setFinishUser(getSessionUser());
			todoEventService.saveOrUpdate(userTodoEvent);
		}
		return LIST;
	}

	public DepartmentService getDepartmentService() {
		return departmentService;
	}

	public void setDepartmentService(DepartmentService departmentService) {
		this.departmentService = departmentService;
	}

	public Map<String, String> getDepartmentList() {
		return departmentList;
	}

	public void setDepartmentList(Map<String, String> departmentList) {
		this.departmentList = departmentList;
	}

	public TodoEventService getTodoEventService() {
		return todoEventService;
	}

	public void setTodoEventService(TodoEventService todoEventService) {
		this.todoEventService = todoEventService;
	}

	public Date getStartDate() {
		return startDate;
	}

	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}

	public Date getEndDate() {
		return endDate;
	}

	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}

	public RoleService getRoleService() {
		return roleService;
	}

	public void setRoleService(RoleService roleService) {
		this.roleService = roleService;
	}

	public TeamService getTeamService() {
		return teamService;
	}

	public void setTeamService(TeamService teamService) {
		this.teamService = teamService;
	}

	public Map<String, String> getRoleList() {
		return roleList;
	}

	public void setRoleList(Map<String, String> roleList) {
		this.roleList = roleList;
	}

	public Map<String, String> getTeamList() {
		return teamList;
	}

	public void setTeamList(Map<String, String> teamList) {
		this.teamList = teamList;
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public LeadsService getLeadsService() {
		return leadsService;
	}

	public void setLeadsService(LeadsService leadsService) {
		this.leadsService = leadsService;
	}

}
